package rssapp

import (
	"gitee.com/captials-team/ubdframe/src/apps"
	httpController "gitee.com/captials-team/ubdframe/src/apps/rssapp/controllers/http"
	"gitee.com/captials-team/ubdframe/src/common"
	"gitee.com/captials-team/ubdframe/src/domain/configstc"
	"gitee.com/captials-team/ubdframe/src/domain/interfaces"
	"gitee.com/captials-team/ubdframe/src/domain/services"
	"gitee.com/captials-team/ubdframe/src/domain/vo"
	"gitee.com/captials-team/ubdframe/src/infrastructure/caches"
	v1log "gitee.com/captials-team/ubdframe/src/pkg/logs"
	"gitee.com/captials-team/ubdframe/src/pkg/rsshelp"
	"gitee.com/captials-team/ubdframe/src/pkg/uber_help"
	"github.com/robfig/cron/v3"
	"go.uber.org/dig"
	"time"
)

type App struct {
	*apps.App

	l          v1log.ILog
	di         *dig.Scope
	ApiServer  *ApiServer
	RssFetcher *rsshelp.RssFetcher
}

func (app *App) initCaches(conf *configstc.RssAppConfig) {
	common.ErrPanic(app.di.Provide(func() caches.ItfCache {
		return caches.NewMemoryStore(time.Minute * 10)
	}), uber_help.ErrAlreadyProvided)

	common.ErrPanic(app.di.Provide(func(cache caches.ItfCache) services.RssCache {
		return caches.NewCacheFacade[string, *vo.RssBody](cache)
	}), uber_help.ErrAlreadyProvided)

	app.l.Info("provide cache success")
}

func (app *App) startCron(f *rsshelp.RssFetcher, conf *configstc.RssAppConfig) {
	//异步初始化
	if conf.AsyncInit {
		go f.Fetch()
	} else {
		f.Fetch()
	}

	//每30分钟获取一次
	c := cron.New()
	c.AddFunc("@every 30m", f.Fetch)
	c.Start()
}

func (app *App) initRss(f *rsshelp.RssFetcher, ca services.RssCache, logger v1log.ILog, conf *configstc.RssAppConfig) {
	app.RssFetcher = f

	for _, v := range conf.RssConfig {
		if v.Enable {
			f.AddRss(v.Name, v.Rss)
		}
	}

	f.AddHandler(func(meta *vo.RssMeta, body *vo.RssBody) {
		err := ca.SetDefault(meta.Name, body)
		logger.Ctl(err != nil).Error("%s", err)
	})
}

func (app *App) initController() {
	common.ErrPanic(app.di.Provide(httpController.NewRssController, dig.As(new(interfaces.ItfRssController))), uber_help.ErrAlreadyProvided)
	common.ErrPanic(app.di.Provide(httpController.NewRssManagerController, dig.As(new(interfaces.ItfRssManageController))), uber_help.ErrAlreadyProvided)
}

func NewApp(di *dig.Container, conf *configstc.RssAppConfig, logger v1log.ILog) *App {
	scope := di.Scope("admin")

	common.ErrPanic(scope.Provide(func() *dig.Scope {
		return scope
	}), uber_help.ErrAlreadyProvided)
	common.ErrPanic(scope.Provide(func() *configstc.RssAppConfig {
		return conf
	}), uber_help.ErrAlreadyProvided)

	app := &App{
		di:  scope,
		l:   logger,
		App: apps.NewApp(di, "rss_app"),
	}

	app.WithModule(conf.ModuleMode)

	//db初始化
	common.ErrPanic(scope.Provide(rsshelp.NewRssFetcher))

	common.ErrPanic(scope.Invoke(app.initCaches))
	common.ErrPanic(scope.Invoke(app.initRss))
	common.ErrPanic(scope.Invoke(app.initController))
	common.ErrPanic(scope.Invoke(app.startCron))

	if conf.ApiServer.Enable {
		common.ErrPanic(scope.Provide(NewApiServer))
		common.ErrPanic(scope.Invoke(func(api *ApiServer) {
			app.WithApiServer(api)
			app.ApiServer = api
		}))
	}

	return app
}
